"""
@File    :   jwt.py
@Time    :   2024/02/19 09:36:43
@Author  :   Qrj
@Email   :   923207736@qq.com
@description   :   Jwt相关工具类
"""

from datetime import datetime, timedelta

from jose import jwt

from src.utils.uuid import UuidUtil

# 令牌签名算法


class JwtUtil:
    """Jwt工具类"""

    @staticmethod
    def jwt_encode(
        secret_key: str,
        algorithm: str = "HS256",
        expire_seconds: int = 3600,
        jwt_unique_token: str | None = None,
        custom_payload: dict[str, str] | None = None,
    ) -> str:
        """生成jwt

        Args:
            payload (dict): jwt载荷, 传递的主体数据
            secret_key (str): 加密秘钥
            algorithm (str, optional): 令牌签名算法, 默认用HS256
            expire_seconds (int, optional): 过期秒数
            jwt_unique_token (str | None, optional): jwt的唯一身份标识, 为None则只用

        Returns:
            str: jwt字符串
        """
        # 当前UTC时间
        now_utc = datetime.now()
        # 签发时间(时间戳)
        iat_timestamp = now_utc.timestamp()
        # 过期时间(时间戳)
        exp_dt = now_utc + timedelta(seconds=expire_seconds)
        exp_timestamp = exp_dt.timestamp()
        # jwt唯一身份标识
        jti = jwt_unique_token or UuidUtil.generate_uuid1()
        # 默认jwt载荷, 传递的主体数据
        payload = {
            "iss": "qy-admin",  # 该jwt由谁签发
            # "sub": "subject",  # jwt的主题
            # "aud": "audience",  # 由谁接收该jwt信息
            "iat": iat_timestamp,  # jwt签发时间
            "nbf": iat_timestamp,  # jwt生效时间
            "exp": exp_timestamp,  # jwt过期时间, 是一个unix时间戳, 必须大于签发时间
            "jti": jti,  # jwt的唯一身份标识, 作为一次性token, 用于回避重放攻击
        }
        if custom_payload:
            # 不允许自定义jwt时间签发、生效和过期时间
            if custom_payload.get("iat"):
                del custom_payload["iat"]
            if custom_payload.get("nbf"):
                del custom_payload["nbf"]
            if custom_payload.get("exp"):
                del custom_payload["exp"]
            payload.update(custom_payload)
        # 生成并返回jwt
        return jwt.encode(payload, secret_key, algorithm=algorithm)

    @staticmethod
    def jwt_decode(
        token: str, secret_key: str, algorithm: str = "HS256"
    ) -> dict[str, str | float]:
        return jwt.decode(token, secret_key, algorithms=algorithm)
